home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 7 / Amiga Format AFCD07 (Dec 1996, Issue 91).iso / serious / shareware / programming / emacs-complete / fsf / emacs / lwlib / lwlib-xol.c < prev    next >
C/C++ Source or Header  |  1994-01-18  |  7KB  |  318 lines

  1. #include "lwlib-Xol.h"
  2. #include <X11/StringDefs.h>
  3. #include <X11/IntrinsicP.h>
  4. #include <X11/CompositeP.h>
  5. #include <X11/Shell.h>
  6. #include <Xol/Menu.h>
  7. #include <Xol/OpenLook.h>
  8. #include <Xol/MenuButton.h>
  9. #include <Xol/OblongButt.h>
  10. #include <Xol/ControlAre.h>
  11. #include <Xol/Stub.h>
  12. #include <Xol/StaticText.h>
  13.  
  14. /* forward declarations */
  15. static void
  16. update_menu_widget (widget_instance* instance, Widget widget,
  17.             widget_value* val);
  18.  
  19. /* Menu callbacks */
  20. static void
  21. pre_hook (Widget w, caddr_t client_data, caddr_t call_data)
  22. {
  23.   OlVirtualEvent ve = (OlVirtualEvent)call_data;
  24.   widget_instance* instance = (widget_instance*)client_data;
  25.  
  26.   if (w->core.being_destroyed)
  27.     return;
  28.  
  29.   if (XtParent (w) == instance->widget)
  30.     {
  31.       if (ve->xevent->type == ButtonPress && instance->info->pre_activate_cb)
  32.     instance->info->pre_activate_cb (instance->widget, instance->info->id,
  33.                      NULL);
  34.     }
  35. }
  36.  
  37. static void
  38. post_hook (Widget w, caddr_t client_data, caddr_t call_data)
  39. {
  40.   widget_instance* instance = (widget_instance*)client_data;
  41.   
  42.   if (w->core.being_destroyed)
  43.     return;
  44.   
  45.   if (instance->info->post_activate_cb)
  46.     instance->info->post_activate_cb (w, instance->info->id, NULL);
  47. }
  48.  
  49. static void
  50. pick_hook (Widget w, caddr_t client_data, caddr_t call_data)
  51. {
  52.   widget_instance* instance = 0;
  53.   widget_value* val = (widget_value*)client_data;
  54.  
  55.   if (w->core.being_destroyed)
  56.     return;
  57.  
  58.   XtVaGetValues (w, XtNuserData, &instance, 0);
  59.  
  60.   if (!instance)
  61.     return;
  62.  
  63.   if (instance->info->selection_cb && val && val->enabled
  64.       && !val->contents)
  65.     instance->info->selection_cb (w, instance->info->id, val->call_data);
  66. }
  67.  
  68. /* creation functions */
  69. static Widget
  70. xol_create_menubar (widget_instance* instance)
  71. {
  72.   Widget widget =
  73.     XtVaCreateWidget (instance->info->name, controlAreaWidgetClass,
  74.               instance->parent, 0);
  75.   return widget;
  76. }
  77.  
  78. static Widget
  79. xol_create_popup_menu (widget_instance* instance)
  80. {
  81.   Widget popup_shell =
  82.     XtCreatePopupShell (instance->info->name, menuShellWidgetClass,
  83.             instance->parent, NULL, 0);
  84.   return popup_shell;
  85. }
  86.  
  87. widget_creation_entry 
  88. xol_creation_table [] =
  89. {
  90.   {"menubar", xol_create_menubar},
  91.   {"popup", xol_create_popup_menu},
  92.   {NULL, NULL}
  93. };
  94.  
  95. Widget 
  96. xol_create_dialog (widget_instance* instance)
  97. {
  98.   return NULL;
  99. }
  100.  
  101. Boolean
  102. lw_olit_widget_p (Widget widget)
  103. {
  104.   return True;
  105. }
  106.  
  107. /* update functions */
  108. static void
  109. destroy_all_children (Widget widget)
  110. {
  111.   Widget* children;
  112.   unsigned int number;
  113.   int i;
  114.  
  115.   children = (Widget *) XtCompositeChildren (widget, &number);
  116.   if (children)
  117.     {
  118.       /* Unmanage all children and destroy them.  They will only be 
  119.        * really destroyed when we get out of DispatchEvent. */
  120.       for (i = 0; i < number; i++)
  121.     {
  122.       Widget child = children [i];
  123.       if (!child->core.being_destroyed)
  124.         {
  125.           XtUnmanageChild (child);
  126.           XtDestroyWidget (child);
  127.         }
  128.     }
  129.       XtFree (children);
  130.     }
  131. }
  132.  
  133. static Boolean
  134. all_dashes_p (char* s)
  135. {
  136.   char* t;
  137.   for (t = s; *t; t++)
  138.     if (*t != '-')
  139.       return False;
  140.   return True;
  141. }
  142.  
  143. static void
  144. make_menu_in_widget (widget_instance* instance, Widget widget,
  145.              widget_value* val)
  146. {
  147.   widget_value* cur;
  148.   Widget button;
  149.   Arg al [256];
  150.   int ac;
  151.   String label;
  152.  
  153.   for (cur = val; cur; cur = cur->next)
  154.     {    
  155.       ac = 0;
  156.       XtSetArg (al [ac], XtNsensitive, cur->enabled); ac++;
  157.       XtSetArg (al [ac], XtNuserData, instance); ac++;
  158.       XtSetArg (al [ac], XtNacceleratorText, cur->key); ac++;
  159.       
  160. /*      label = (char *) resource_string (widget, cur->name);*/
  161.       label = cur->name;
  162.       if (label)
  163.     {
  164.       XtSetArg (al [ac], XtNlabel, label); ac++;
  165.     }
  166.  
  167.       if (all_dashes_p (cur->name))
  168.     {
  169.       /* no separator in OpenLook just make some space. */
  170.       XtSetArg (al [ac], XtNheight, 5); ac++;
  171.       XtSetArg (al [ac], XtNwidth, 5); ac++;
  172.       button = XtCreateWidget (cur->name, stubWidgetClass, widget, al, ac);
  173.     }
  174.       else if (!cur->contents)
  175.     {
  176.       if (!cur->call_data)
  177.         button =
  178.           XtCreateManagedWidget (cur->name, staticTextWidgetClass, widget,
  179.                      al, ac);
  180.       else
  181.         {
  182.           button =
  183.         XtCreateManagedWidget (cur->name, oblongButtonWidgetClass,
  184.                        widget, al, ac);
  185.           XtAddCallback (button, XtNselect, pick_hook, cur);
  186.         }
  187.     }
  188.       else
  189.     {
  190.       Widget menu = NULL;
  191.       button =
  192.         XtCreateManagedWidget (cur->name, menuButtonWidgetClass, widget,
  193.                    al, ac);
  194.       XtVaGetValues (button, XtNmenuPane, &menu, 0);
  195.       if (!menu)
  196.         abort ();
  197.       make_menu_in_widget (instance, menu, cur->contents);
  198.       OlAddCallback (button, XtNconsumeEvent, pre_hook, instance);
  199.     }
  200.     }
  201. }
  202.  
  203. static void
  204. update_one_menu_entry (widget_instance* instance, Widget widget,
  205.                widget_value* val)
  206. {
  207.   Arg al [256];
  208.   int ac;
  209.   Widget menu;
  210.   widget_value* contents;
  211.  
  212.   if (val->change == NO_CHANGE)
  213.     return;
  214.  
  215.   /* update the sensitivity */
  216.   XtVaSetValues (widget, XtNsensitive, val->enabled, 0);
  217.  
  218.   /* update the pulldown/pullaside as needed */
  219.   ac = 0;
  220.   menu = NULL;
  221.   XtVaGetValues (widget, XtNmenuPane, &menu, 0);
  222.   contents = val->contents;
  223.  
  224.   if (!menu)
  225.     {
  226.       if (contents)
  227.     {
  228.       /* in OLIT this woudl have to be a structural change on the
  229.          button. */
  230.       abort ();
  231.     }
  232.     }
  233.   else if (!contents)
  234.     {
  235.       /* in OLIT this woudl have to be a structural change on the button. */
  236.       abort ();
  237.     }
  238.   else if (contents->change != NO_CHANGE)
  239.     update_menu_widget (instance, menu, val);
  240. }
  241.  
  242. static void
  243. update_menu_widget (widget_instance* instance, Widget widget,
  244.             widget_value* val)
  245.  
  246. {
  247.   if (val->change == STRUCTURAL_CHANGE
  248.       || val->contents->change == STRUCTURAL_CHANGE)
  249.     {
  250.       destroy_all_children (widget);
  251.       make_menu_in_widget (instance, widget, val->contents);
  252.     }
  253.   else
  254.     {
  255.       /* Update all the buttons of the composite widget in order. */
  256.       Widget* children;
  257.       unsigned int num_children;
  258.       int i;
  259.       widget_value* cur;
  260.       
  261.       children = (Widget *) XtCompositeChildren (widget, &num_children);
  262.       if (children)
  263.     {
  264.       for (i = 0, cur = val->contents; i < num_children; i++)
  265.         {
  266.           if (!cur)
  267.         abort ();
  268.           if (children [i]->core.being_destroyed
  269.           || strcmp (XtName (children [i]), cur->name))
  270.         continue;
  271.           update_one_menu_entry (instance, children [i], cur);
  272.           cur = cur->next;
  273.         }
  274.       XtFree (children);
  275.     }
  276.       if (cur)
  277.     abort ();
  278.     }
  279. }
  280.  
  281. void
  282. xol_update_one_widget (widget_instance* instance, Widget widget,
  283.                widget_value* val, Boolean deep_p)
  284. {
  285.   Widget menu = widget;
  286.  
  287.   if (XtIsShell (widget))
  288.     XtVaGetValues (widget, XtNmenuPane, &menu, 0);
  289.  
  290.   update_menu_widget (instance, menu, val);
  291. }
  292.  
  293. void
  294. xol_update_one_value (widget_instance* instance, Widget widget,
  295.               widget_value* val)
  296. {
  297.   return;
  298. }
  299.  
  300. void
  301. xol_pop_instance (widget_instance* instance, Boolean up)
  302. {
  303. }
  304.  
  305. void
  306. xol_popup_menu (Widget widget)
  307. {
  308.   OlMenuPost (widget);
  309. }
  310.  
  311. /* Destruction of instances */
  312. void
  313. xol_destroy_instance (widget_instance* instance)
  314. {
  315.   XtDestroyWidget (instance->widget);
  316. }
  317.  
  318.